package persistencia.dao;

import java.util.Date;
import java.util.List;

import org.hibernate.Query;
import bean.EntidadPersistente;
import bean.ItemListaPrecios;
import bean.ListaPrecios;
import bean.Producto;
import bean.Proveedor;
import bean.vo.ProductoVO;
import persistencia.hbt.HibernateUtil;

@SuppressWarnings("unchecked")
public class ListaPreciosDAO extends EntidadPersistenteDAO {
	private static ListaPreciosDAO instancia = null;
	
	public static ListaPreciosDAO getInstancia(){
		if(instancia == null)
			instancia = new ListaPreciosDAO();
		
		if (session == null)
			session = HibernateUtil.getSession();
		
		return instancia;
	}
	
	public ListaPrecios buscarListaActivaParaProveedorConVigencia(Proveedor proveedor, Date desde, Date hasta)
	{
		String q = "select l.* from ListaPrecios l where l.proveedor = :prov and l.activa = true ";
		
		if (desde != null)
			q += " and l.fechaEmision <= :desde ";
		
		if (hasta != null)
			q += " and l.fechaCaducidad >= :hasta ";
		
		Query query = session.createQuery(q);
		query.setEntity("prov", proveedor);
		
		if (desde != null)
			query.setDate("desde", desde);
		
		if (hasta != null)
			query.setDate("hasta", hasta);
		
		ListaPrecios lista = (ListaPrecios) query.setFirstResult(0).setMaxResults(1).uniqueResult();

		return lista;
	}
	
	public ListaPrecios buscar(EntidadPersistente entidad)
	{
		ListaPrecios lista = (ListaPrecios) entidad;
		
		if (lista.getId() != null)
			return (ListaPrecios) super.buscar(lista);
		else if (lista.getNumeroLista() != null && lista.getProveedor() != null)
			return this.buscar(lista.getNumeroLista(), lista.getProveedor());
		
		return null;
	}
	
	private ListaPrecios buscar(Integer nroLista, Proveedor proveedor){
		Query query = session.createQuery("from ListaPrecios l where l.numeroLista = :num and l.proveedor = :prov");
		query.setInteger("num", nroLista);
		query.setEntity("prov", proveedor);
		
		ListaPrecios lista = (ListaPrecios) query.setFirstResult(0).setMaxResults(1).uniqueResult();

		return lista;
	}
	
	public ItemListaPrecios obtenerMejorPrecioParaProducto(Producto producto, int cantidad) {
		ItemListaPrecios mejorPrecio = null;
		
		String q = "select i from ListaPrecios l, ItemListaPrecios i where i.listaPrecio = l " +
				" and l.activa = true and l.fechaEmision <= :desde and l.fechaCaducidad >= :hasta " +
				" and i.producto = :producto and (i.cantidadMinima <= :cantidad or i.cantidadMinima is null) " +
				" order by i.precio asc " ;
		
		Query query = session.createQuery(q);
		query.setDate("desde", new Date());
		query.setDate("hasta", new Date());
		query.setEntity("producto", producto);
		query.setInteger("cantidad", cantidad);
		
		mejorPrecio = (ItemListaPrecios) query.setFirstResult(0).setMaxResults(1).uniqueResult();
		
		return mejorPrecio;
	}
	
	public List<ItemListaPrecios> obtenerComparativaDePrecios(ProductoVO producto) {

		String q = "select i from ListaPrecios l, ItemListaPrecios i where i.listaPrecio = l " +
				" and l.activa = true and l.fechaEmision <= :desde and l.fechaCaducidad >= :hasta ";
		
		String codigo = producto.getRodamiento() != null ? producto.getRodamiento().getCodigo() : null;
		String sufijo = producto.getRodamiento() != null ? producto.getRodamiento().getSufijo() : null;
		String fabricante = producto.getFabricante() != null ? producto.getFabricante().getNombre() : null;
		String origen = producto.getOrigen() != null ? producto.getOrigen().getNombre() : null;
		
		if (codigo != null) {
			q += " and i.producto.rodamiento.codigo = :codigo ";
		}
		
		if (sufijo != null) {
			q += " and i.producto.rodamiento.sufijo = :sufijo ";
		}
		
		if (fabricante != null) {
			q += " and i.producto.fabricante.nombre = :fabricante ";
		}
		
		if (origen != null) {
			q += " and i.producto.origen.nombre = :origen ";
		}
		
		Query query = session.createQuery(q);
		query.setDate("desde", new Date());
		query.setDate("hasta", new Date());
		
		if (codigo != null) {
			query.setString("codigo", codigo);
		}
		
		if (sufijo != null) {
			query.setString("sufijo", sufijo);
		}
		
		if (fabricante != null) {
			query.setString("fabricante", fabricante);
		}
		
		if (origen != null) {
			query.setString("origen", origen);
		}
		
		return query.list();
	}
	
}
